package com.huawei.bitfun.insight.database;

import com.huawei.bitfun.insight.type.converter.RowConverter;
import com.huawei.deveco.insight.ohos.common.ProfilerError;
import com.huawei.deveco.insight.ohos.common.ProfilerException;
import org.apache.commons.dbcp2.BasicDataSource;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class DatabaseManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseManager.class);

    public static <T> @NotNull QueryDataType<T> queryData(String sql, BasicDataSource dataSource, RowConverter<T> rowConverter) {
        List<T> list = new ArrayList<>();
        QueryDataType<T> queryDataType = new QueryDataType<>();
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet res = ps.executeQuery()) {
//            res.getMetaData().getColumnName()
            while (res.next()) {
                T row = rowConverter.mapToRow(res);
                list.add(row);
            }
            // get column name list
            ResultSetMetaData metaData = res.getMetaData();
            int columnCount = metaData.getColumnCount();
            List<String> columnNames = new ArrayList<>();
            for (int i = 1; i <= columnCount; i++) {
                columnNames.add(metaData.getColumnName(i));
            }
            queryDataType.setDataList(list);
            queryDataType.setColumnList(columnNames);
            return queryDataType;
        } catch (SQLException e) {
            throw new ProfilerException(ProfilerError.SQL_ERROR, e.getMessage());
        }
    }

    public static boolean updateData(String sql, BasicDataSource dataSource, Object... params) {
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            int res = ps.executeUpdate();
            return res > 0;
        } catch (SQLException e) {
            LOGGER.warn("query datasource error", e);
            return false;
        }
    }
}
